home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
TERMINAL
/
SRCS
/
INIT.C
< prev
next >
Wrap
Text File
|
1990-11-20
|
14KB
|
550 lines
/*
Terminal 2.0
"Init.c"
Note: In the final application use ResEdit to clear the locked
bit of the CODE resource containing this segment. In this way the
initialisation code gets loaded high in the application heap and
all non-movable objects created (like strings, windows, master
pointers, buffers...) will be allocated at the start of the
application heap without any heap fragmentation when the
initialisation code is again unloaded.
*/
#ifdef THINK_C
#include "MacHeaders"
#endif
#ifdef applec
#pragma load ":(Objects):MacHeadersMPW"
#pragma segment Init
#endif
#include "Text.h"
#include "Main.h"
#include "Strings.h"
#include "Utilities.h"
#include "CRC.h"
#include "Serial.h"
#include "File.h"
#include "Macros.h"
/* Trap numbers */
#define TN_UnknownOS 0xA09F
#define TN_CommToolbox 0xA08B
#define TN_UnknownTool 0xA89F
#define TN_PopUpMenuSelect 0xA80B
#define TN_WaitNextEvent 0xA860
#define TN_ScriptUtil 0xA8B5
#define TN_KeyTrans 0xA9C3
#define TN_OSDispatch 0xA88F
#define INSET 2
#define BAR 16 /* Scroll bar width */
#define TLEFT 2 /* Default terminal window position */
#define TTOP 40
#define PLEFT 26 /* Default progress window position */
#define PTOP 83
/* ----- Read information from 'CNFG' resource ------------------------- */
static void ReadConfig(void)
{
register Configuration **h;
/* Read configuration resource. If not available use defauts. */
if (h = (Configuration **)GetResource('CNFG', 128)) {
HLock((Handle)h);
memcpy(&Config, *h, sizeof(Config));
GetFNum((**h).fontname, &Config.font);
ReleaseResource((Handle)h);
} else {
Config.font = monaco;
Config.size = 9;
Config.lines = 24;
Config.columns = 81;
Config.buffer = 0x8000;
Config.input = 0x2000;
Config.output = 64;
Config.script = 4096;
}
}
/* ----- Read information from 'BNDL' resource ------------------------- */
typedef struct {
short local; /* Local ID */
short actual; /* Actual resource ID */
} LOCAL;
typedef struct {
long type; /* Resource type 'ICN#' or 'FREF' */
short count; /* Number of resources - 1 (must be 2) */
LOCAL id[3];
} TYPE;
typedef struct {
long signature; /* Signature of the application */
short version; /* Resource ID of version data */
short types; /* Number of resource types - 1 (must be 1) */
TYPE info[2];
} BUNDLE;
typedef struct {
long type; /* File type */
short local; /* Local ID for icon list */
} FREF;
static void Bundle(void)
{
register BUNDLE **h;
register BUNDLE *p;
register FREF **f;
register short i, j;
Application.version = 0;
Application.icon = 128;
Application.signature =
Application.otype =
Application.btype =
Application.stype =
Application.ztype = '????';
if (h = (BUNDLE **)GetIndResource('BNDL', 1)) {
HLock((Handle)h);
p = *h;
Application.signature = p->signature;
Application.version = p->version;
for (i = 0; i <= p->types; i++)
switch (p->info[i].type) {
case 'ICN#':
for (j = 0; j <= p->info[i].count; j++)
if (p->info[i].id[j].local == 0) {
Application.icon = p->info[i].id[j].actual;
break;
}
break;
case 'FREF':
for (j = 0; j <= p->info[i].count; j++) {
if (f = (FREF **)
GetResource('FREF', p->info[i].id[j].actual)) {
register long t = (**f).type;
ReleaseResource((Handle)f);
switch (p->info[i].id[j].local) {
case 1: /* Options */
Application.otype = t;
break;
case 2: /* MacBinary */
Application.btype = t;
break;
case 3: /* Script */
Application.stype = t;
break;
case 4: /* Z-modem part */
Application.ztype = t;
break;
}
}
}
break;
}
ReleaseResource((Handle)h);
}
}
/* ----- Make sure window is on desktop -------------------------------- */
static void WindowScreen(
Point *p,
short dh,
short dv)
{
RgnHandle rgn;
if (!(rgn = NewRgn()))
return;
SetRectRgn(rgn, p->h, p->v - 15, p->h + 50, p->v + 15);
UnionRgn(GrayRgn, rgn, rgn);
if (!EqualRgn(GrayRgn, rgn)) {
p->h = dh;
p->v = dv;
}
DisposeRgn(rgn);
}
/* ----- Read options -------------------------------------------------- */
static void ReadOptions(void)
{
short err;
short volume;
long directory, scriptDirectory;
long count;
Byte volname[28];
/* Get volume and folder where application is */
{
WDPBRec vol;
vol.ioCompletion = 0;
vol.ioNamePtr = 0;
if (PBHGetVol(&vol, FALSE)) {
volume = Mac.sysVRefNum;
directory = 2;
} else {
volume = vol.ioWDVRefNum;
directory = vol.ioWDDirID;
}
VolumeId(volname, &volume);
}
/* If there is a script folder in the application folder use it,
else use application folder as script folder */
{
CInfoPBRec pb;
scriptDirectory = directory;
pb.dirInfo.ioCompletion = 0;
pb.dirInfo.ioNamePtr = (StringPtr)MyString(STR_G, G_SCRIPTFOLDER);
pb.dirInfo.ioVRefNum = volume;
pb.dirInfo.ioFDirIndex = 0;
pb.dirInfo.ioDrDirID = directory;
if (!PBGetCatInfo(&pb, FALSE) && (pb.dirInfo.ioFlAttrib & 0x10))
scriptDirectory = pb.dirInfo.ioDrDirID;
}
/* Read settings file from script folder */
{
short r;
if (!(err = OpenFile(volume, scriptDirectory,
MyString(STR_G,G_SETTINGS), &r))) {
count = sizeof(Settings);
err = FSRead(r, &count, (Ptr)&Settings);
FSClose(r);
}
}
/* If a valid settings file is found, use it, else use defaults */
if (err || count != sizeof(Settings) || Settings.version != SETTINGS ||
CalcCRC((Byte *)&Settings + sizeof(short),
sizeof(Settings) - sizeof(short), 0) != Settings.crc) {
/* Communication options */
*Settings.portName = 0;
Settings.portSetup = baud2400+stop10+noParity+data8;
Settings.dropDTR = FALSE;
/* TEXT file send options */
Settings.prompt[0] = 0;
Settings.linedelay = 0;
Settings.chardelay = 0;
Settings.handshake = 0;
/* Binary file transfer options */
Settings.Binary = TRUE;
memcpy(Settings.volumeName, volname, volname[0] + 1);
Settings.volume = volume;
Settings.directory = directory;
Settings.protocol = 0;
Settings.ZModem = FALSE;
Settings.ZAutoReceive = FALSE;
/* XYModem options */
Settings.XModemtimeout = 600; /* 10 s */
Settings.XModemCRC = TRUE;
Settings.XModem1K = 0;
Settings.batch = 0;
/* ZModem options */
Settings.ZEscapeCtl = FALSE;
Settings.ZTimeout = 600; /* 10 s */
Settings.ZBuffer = 0;
Settings.ZRetries = 10;
Settings.ZPacket = 1024;
Settings.ZWindow = 0;
Settings.Zcrcq = 0;
/* Terminal options */
Settings.localEcho = FALSE;
Settings.echo = FALSE;
Settings.autoLF = FALSE;
Settings.save = TRUE;
/* Settings.scriptVolume */
/* Settings.scriptDirectory */
Settings.startVName[0] = 0;
Settings.startVolume = 0;
Settings.startDirectory = 0;
Settings.startName[0] = 0;
/* Other options */
Settings.textCreator = 'PEDT';
Settings.binType = TEXT;
Settings.binCreator = 'PEDT';
Settings.backspace = 0x08;
Settings.escape = 0x1B;
Settings.beep = FALSE;
Settings.ctrl = 0;
/* Window positions */
Settings.terminalWindow.h = TLEFT;
Settings.terminalWindow.v = TTOP;
Settings.progressWindow.h = PLEFT;
Settings.progressWindow.v = PTOP;
} else {
/* Make sure left corner of windows is on desktop */
WindowScreen(&Settings.terminalWindow, TLEFT, TTOP);
WindowScreen(&Settings.progressWindow, PLEFT, PTOP);
}
Settings.scriptVolume = volume;
Settings.scriptDirectory = scriptDirectory;
Settings.dirty = FALSE;
/* Make sure volume reference numbers and volume names are ok.
This is necessary if booting from different disks. */
Settings.volume = 0;
if (VolumeId(Settings.volumeName, &Settings.volume)) {
Settings.volume = volume;
memcpy(Settings.volumeName, volname, volname[0] + 1);
Settings.directory = directory;
}
Settings.startVolume = 0;
if (Settings.startVName[0])
VolumeId(Settings.startVName, &Settings.startVolume);
}
/* ----- Set up new text record ---------------------------------------- */
static long InitTextRecord(
register TextRecord *p,
register long size)
{
p->lines = 1;
p->firstChar = p->newChar = p->length = p->viewChar = p->viewLine = 0;
if (size = (p->text = (Byte *)NewPtr(size)) ? (p->size = size) : 0)
(p->text)[0] = '\015';
return size;
}
/* ----- Set up script menu items -------------------------------------- */
static void ScriptsInit(void)
{
register MenuHandle mh;
register short i;
register Byte *p;
register Byte *q;
register Byte *suffix = (Byte *)MyString(STR_G, G_SUFFIX);
Byte name[256];
HParamBlockRec pb;
short menuitem = 2;
if (!(mh = GetMenu(SCRIPT)))
return;
for (i = 1; ; i++) {
pb.ioParam.ioCompletion = 0;
pb.ioParam.ioVRefNum = Settings.scriptVolume;
pb.fileParam.ioDirID = Settings.scriptDirectory;
pb.ioParam.ioNamePtr = (StringPtr)name;
pb.fileParam.ioFDirIndex = i;
if (PBHGetFInfo(&pb, FALSE))
break;
if (pb.fileParam.ioFlFndrInfo.fdType == TEXT)
for (p = name + *name, q = suffix + *suffix; ; --p, --q) {
if (q == suffix) { /* Show the file */
*name -= *suffix; /* Strip suffix */
/* This AppendMenu() followed by SetItem() is necessary
if there are any of the menu meta characters ( ';' '^'
'!' '<' '/' '(' ) in the name. */
AppendMenu(mh, "\p ");
SetItem(mh, ++menuitem, name);
break;
}
if (p == name || *q != *p) /* Don't show file */
break;
}
}
}
/* ----- Create new document record ------------------------------------ */
static DocumentPeek NewDocument(void)
{
register DocumentPeek window;
FontInfo info;
Rect r;
if (window = (DocumentPeek)NewPtr(sizeof(DocumentRecord))) {
/* Make new window and get font characteristics */
r = QD(screenBits.bounds); /* Will be adjusted later */
if (!NewWindow((void *)window, &r,
(char *)MyString(STR_G, G_TERMINAL),
FALSE, noGrowDocProc, (WindowPtr)-1L, TRUE, 0)) {
DisposPtr((Ptr)window);
return 0;
}
SetPort((GrafPtr)window);
TextFont(Config.font);
TextFace(0);
TextMode(srcOr);
TextSize(Config.size);
GetFontInfo(&info);
info.widMax = CharWidth('M'); /* widMax not always correct */
/* Initialize document fields */
if (!InitTextRecord(&window->buf, Config.buffer)) {
DisposeWindow((WindowPtr)window);
return 0;
}
window->file = window->volume = 0;
window->length = 0;
/* Adjust window size and position */
r.top = 21;
r.left = 0;
r.bottom = r.top + 2*INSET + Config.lines * (window->height =
info.ascent + info.descent + info.leading);
r.right = r.left + 2*INSET + Config.columns * info.widMax;
window->rect = r;
InsetRect(&window->rect, INSET, INSET);
window->cursor0.v = window->rect.top + info.ascent;
window->cursor0.h = window->rect.left;
window->cursor = window->cursor0;
window->linesPage = Config.lines;
window->character.top = - info.ascent;
window->character.left = 0;
window->character.bottom = info.descent;
window->character.right = info.widMax;
r.top = 0;
r.right += BAR - 1;
OffsetRect(&r,Settings.terminalWindow.h,Settings.terminalWindow.v);
MoveWindow((WindowPtr)window, r.left, r.top, FALSE);
SizeWindow((WindowPtr)window, r.right - r.left,
r.bottom - r.top, TRUE);
/* Create window controls */
r.top = window->rect.top - INSET - 1;
r.left = window->rect.right + INSET;
r.bottom = window->rect.bottom + INSET + 1;
r.right = r.left + BAR;
if (window->vs = NewControl((WindowPtr)window, &r, EmptyStr, TRUE,
0, 0, 0, scrollBarProc, 0)) {
r.top = 2;
r.left = 2;
r.bottom = r.top + 16;
r.right = r.left + 30;
window->messOk = NewControl((WindowPtr)window, &r, "\p\022",
FALSE, 0, 0, 0, pushButProc, 0);
window->messRect.top = 1;
window->messRect.left = 34;
window->messRect.bottom = window->rect.top - INSET - 2;
window->messRect.right = window->rect.right + INSET + BAR
- 2;
window->mess[0] = 0;
ShowWindow((WindowPtr)window);
} else {
DisposeWindow((WindowPtr)window);
return 0;
}
}
return window;
}
/* ----- See if a given trap is available ------------------------------- */
static Boolean TrapAvailable(
register short num,
register short type)
{
if (type == ToolTrap &&
Mac.machineType > envMachUnknown &&
Mac.machineType < envMacII) {
num &= 0x03FF;
if (num > 0x01FF)
num = TN_UnknownTool;
}
return NGetTrapAddress(num, type) !=
GetTrapAddress((type == OSTrap) ? TN_UnknownOS : TN_UnknownTool);
}
/* ----- One time initialization ---------------------------------------- */
#ifdef USECTB
pascal OSErr InitCRM(void);
#endif
Boolean Init(void)
{
register short err;
register Handle h;
pascal void Crash();
EventRecord event;
for (err = 0; err < 4; ++err)
MoreMasters();
InitGraf(&QD(thePort));
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(Crash);
InitCursor();
for (err = 0; err < 3; ++err)
EventAvail(everyEvent, &event);
TerminalWindow = 0;
SysEnvirons(1, &Mac);
if (Mac.machineType < 0 ||
!TrapAvailable(TN_PopUpMenuSelect, ToolTrap)) { /* Old Mac */
Error(0, MyString(STR_M, M_OLD));
return TRUE;
}
WNE = TrapAvailable(TN_WaitNextEvent, ToolTrap);
KCHR = (TrapAvailable(TN_ScriptUtil, ToolTrap) &&
TrapAvailable(TN_KeyTrans, ToolTrap)) ?
GetResource('KCHR', GetScript(smRoman, smScriptKeys)) : 0;
MFmemory = TrapAvailable(TN_OSDispatch, ToolTrap);
#ifdef USECTB
if (CTB = TrapAvailable(TN_CommToolbox, OSTrap))
InitCRM();
#endif
Background = FALSE;
ReadConfig();
ReadOptions();
Bundle();
if (!(h = GetNewMBar(MENUBAR)))
return TRUE;
SetMenuBar(h);
DisposHandle(h);
if (h = (Handle)GetMHandle(APPLE))
AddResMenu((MenuHandle)h, 'DRVR');
ScriptsInit();
DrawMenuBar();
TerminalWindow = NewDocument();
if (TerminalWindow &&
(err = SerialOpen(Settings.portName, Settings.portSetup,
Settings.handshake)))
Error(err, EmptyStr);
return TerminalWindow == 0;
}